package cn.cutie.clot.gateway.plugin;

import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @Description: 请求什么返回什么
 * @Author: Cutie
 * @CreateDate: 2024/6/5 00:53
 * @Version: 0.0.1
 */
@Component("directPlugin")
public class DirectPlugin extends AbstractGatewayPlugin{

    public static final String NAME = "direct";
    private String prefix = GATEWAY_PREFIX +"/"+ NAME + "/";
    @Override
    public Mono<Void> doHandle(ServerWebExchange exchange, GatewayPluginChain chain) {
        System.out.println("===>>> [DirectPlugin] ...");
        String backend = exchange.getRequest().getQueryParams().getFirst("backend");
        Flux<DataBuffer> requestBody = exchange.getRequest().getBody();



        if (backend == null || backend.isEmpty()){
            return requestBody.flatMap(dataBuffer -> exchange.getResponse().writeWith(Mono.just(dataBuffer)))
                    .then(chain.handle(exchange));
        }

        WebClient client = WebClient.create(backend);
        Mono<ResponseEntity<String>> entity = client.post()
                .header("Content-Type", "application/json")
                .body(requestBody, DataBuffer.class).retrieve().toEntity(String.class);
        // 6. 通过entity获取响应报文
        Mono<String> body = entity.map(ResponseEntity::getBody);
        //body.subscribe(souce -> System.out.println("response:" + souce));
        // 7. 组装响应报文
        HttpHeaders headers = exchange.getResponse().getHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("clot.gw.version", "v1.0.0");
        headers.add("clot.gw.plugin", getName());

        return body.flatMap(x -> exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(x.getBytes()))))
                .then(chain.handle(exchange));
    }

    @Override
    public boolean doSupport(ServerWebExchange exchange) {
        return exchange.getRequest().getPath().value().startsWith(prefix);
    }

    @Override
    public String getName() {
        return NAME;
    }
}
